package org.onejava.core.manage;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.onejava.core.annotation.AopInfo;
import org.onejava.core.aop.inter.IAfter;
import org.onejava.core.aop.inter.IAfterReturn;
import org.onejava.core.aop.inter.IAfterThrowing;
import org.onejava.core.aop.inter.IBefore;
import org.onejava.core.bean.Allconfig;
import org.onejava.core.bean.AopEntity;
import org.onejava.core.tools.ObjectTools;
import org.onejava.core.tools.ScanTool;


public class AopManage extends BaseManage{
	private static AopManage manage;
	private HashMap<String,AopEntity> entityMap;
	private static  Log log = LogFactory.getLog(AopManage.class);
	
	private AopManage(){}
	
	/**
	 * 获取单例
	 * @return
	 */
	public static AopManage getMamage(){
    	if(null==manage){
    		manage = new  AopManage();
		}
		return manage;
    }
	
	public  AopEntity getService(String name) throws Exception{
		return entityMap.get(name);
	}
	
	public ArrayList<AopEntity> getAopChain(String[] chain) throws Exception{
		ArrayList<AopEntity> list = new ArrayList<AopEntity>();
		if(null==chain||chain.length==0||null==entityMap){
			return list;
		}
		for(int i=0;i<chain.length;i++){
			if("".equals(chain[i]))
				continue;
			AopEntity ae =  entityMap.get(chain[i]);
			if(null==ae){
				throw new Exception(chain[i]+":没有找到这个AOP");
			}
			list.add(ae);	
		}
		return list;
	}
	
	public void intiMap(String packagePath) throws Exception{
		if(null!=entityMap){
			return;
		}
		//扫描出所有AOP路径
		ScanTool sacntool = new ScanTool();
		List<String> list = sacntool.getAllClassName(Allconfig.truePath,packagePath);
		log.info("开始在路径<"+packagePath+">下扫描AOP");
		entityMap = new HashMap<String, AopEntity>();
		for(int i=0;i<list.size();i++){
			Object obj = ObjectTools.getTheObject(list.get(i));
			Map map =getInfo(obj);
			if("".equals(map.get("name"))){
				continue;
			}
			AopEntity ae = new AopEntity((String) map.get("name"),obj,getInterFace(obj));
			setBean(ae);
			entityMap.put((String) map.get("name"), ae);
		}
		log.info(entityMap);
	}
	
	public void  doAop(String name,Throwable ex){
		
	}
	/**
	 * 获取interfaceMap
	 * @return
	 * @throws Exception
	 */
	private Map<String,Integer> getInterFace(Object obj) throws Exception{
		Map<String,Integer> map = new HashMap<String, Integer>();
		Class<?>[] interfaces = obj.getClass().getInterfaces();
		int num = interfaces.length;
		if(interfaces.length==0){
			throw new Exception("Aop:"+obj.getClass()+"未继承正确的接口");
		}
		for(int i=0;i<num;i++){
			if(IBefore.class.equals(interfaces[i])){
				map.put("IBefore", 0);
			}else if(IAfter.class.equals(interfaces[i])){
				map.put("IAfter", 0);
			}else if(IAfterReturn.class.equals(interfaces[i])){
				map.put("IAfterReturn", 0);
			}else if(IAfterThrowing.class.equals(interfaces[i])){
				map.put("IAfterThrowing", 0);
			}
		}
		if(map.size()==0){
			throw new Exception("Aop:"+obj.getClass()+"未继承正确的接口");
		}
		return map;
		
	}
	
	/**
	 * 获取Service的注解信息
	 * @param msa
	 * @return Map
	 */
	private Map getInfo(Object obj) throws Exception{
		AopInfo annotation = (obj.getClass()).getAnnotation(AopInfo.class);
		Map map  = new HashMap();
		if(null!=annotation){
			String name = annotation.name();
			map.put("name", name);
		}else{
			map.put("name", "");
		}
		return map;
	} 
	
}
